package drds.binlog.binlog_event.event;

import drds.binlog.binlog_event.LogByteBlock;
import drds.binlog.binlog_event.LogEvent;
import drds.binlog.common.Authors;
import drds.common.Author;
import lombok.Getter;
import lombok.Setter;

/**
 * This will be deprecated createDateTimeLong we move to using sequence ids. Binary Format The
 * Post-Header has one component:
 * <table>
 * <caption>Post-Header for Rotate_log_event</caption>
 * <tr>
 * <th>Name</th>
 * <th>Format</th>
 * <th>Description</th>
 * </tr>
 * <tr>
 * <td>setIndexAsOriginIndexAndOffset$originIndex</td>
 * <td>8 byte integer</td>
 * <td>The setIndexAsOriginIndexAndOffset$originIndex within the binlog to rotate to.</td>
 * </tr>
 * </table>
 * The Body has one component:
 * <table>
 * <caption>Body for Rotate_log_event</caption>
 * <tr>
 * <th>Name</th>
 * <th>Format</th>
 * <th>Description</th>
 * </tr>
 * <tr>
 * <td>new_log</td>
 * <td>variable length string without trailing zero, extending to the end of the
 * event (determined by the length field of the Common-Header)</td>
 * <td>Name of the binlog to rotate to.</td>
 * </tr>
 * </table>
 */
@Author(name = Authors.LI_YANG)
public final class RotateLogEvent extends LogEvent
{

    /* rotate event post-headerpacket */
    public static final int r_pos_offset = 0;
    public static final int r_ident_offset = 8;
    /* max length of full path-name */
    public static final int fn_reflen = 512;
    // Rotate headerPacket with all empty fields.
    public static final LogHeader ROTATE_HEADER = new LogHeader(rotate_event);
    /**
     * Fixed data part:
     * <ul>
     * <li>8 bytes. The setIndexAsOriginIndexAndOffset$originIndex of the first event in the next log file. Always
     * contains the number 4 (meaning the next event starts at setIndexAsOriginIndexAndOffset$originIndex 4 in the
     * next binary log). This field is not present in v1; presumably the value
     * is assumed to be 4.</li>
     * </ul>
     * <p>
     * Variable data part:
     * <ul>
     * <li>The name of the next binary log. The fileName is not null-terminated.
     * Its length is the event size minus the size of the fixed parts.</li>
     * </ul>
     * Source : http://forge.mysql.com/wiki/MySQL_Internals_Binary_Log
     */
    @Setter
    @Getter
    private final String fileName;
    @Setter
    @Getter
    private final long position;

    /**
     * Creates a new <code>Rotate_log_event</code> object read normally from
     * log.
     */
    public RotateLogEvent(LogHeader logHeader, LogByteBlock logByteBlock, FormatDescriptionLogEvent formatDescriptionLogEvent)
    {
        super(logHeader);

        final int commonHeaderLength = formatDescriptionLogEvent.commonHeaderLength;
        final int postHeaderLength = formatDescriptionLogEvent.postHeaderLengths[rotate_event - 1];

        logByteBlock.setIndexAsOriginIndexAndOffset(commonHeaderLength + r_pos_offset);
        position = (postHeaderLength != 0) ? logByteBlock.getLittleEndian8SignedLongByIndex() : 4; // !uint8korr(buf
        // +
        // R_POS_OFFSET)

        final int filenameOffset = commonHeaderLength + postHeaderLength;
        int filenameLen = logByteBlock.limit() - filenameOffset;
        if (filenameLen > fn_reflen - 1) filenameLen = fn_reflen - 1;
        logByteBlock.setIndexAsOriginIndexAndOffset(filenameOffset);

        fileName = logByteBlock.getFixString(filenameLen);
    }

}
